-
-
Notifications
You must be signed in to change notification settings - Fork 436
operations: add GPG key management operations (pr 1/3) #1460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 3.x
Are you sure you want to change the base?
Conversation
6521c5b
to
5585d21
Compare
Add new gpg.key and gpg.dearmor operations to manage GPG keys and keyrings. These operations provide a modern alternative to apt-key for managing APT repository keys. Features: - Install keys from URLs, local files, or keyservers - Remove keys by ID or entire keyring files - Convert ASCII armored keys to binary format - Manage keys in specific keyrings or across all APT keyrings This is part 1/3 of modernizing APT key management.
5585d21
to
8d3ea39
Compare
Hi @DonDebonair ! |
Thanks for the PR @maisim . I would not be afraid to use facts inside operations. I actually consider it a best practice to use facts to check things in operations. So instead of doing checks inside the shell commands you yield, there are probably places where you can rely on facts instead. That makes the yielded commands simpler. If you can change those already, I'll do a more full review this weekend. Caveat btw: I'm by no means a GPG expert. A short while ago, I wanted to use pyinfra to install Docker on a Debian host. I just created the keyring directory and downloaded the key directly into that, never touching GPG 😅 |
for kid in keyid: | ||
# Remove key from all matching keyrings | ||
yield ( | ||
f'for keyring in {pattern}; do [ -e "$keyring" ] && ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't it make more sense to retrieve keyrings through a fact and then only try to remove the key from keyrings that actually exist?
Or maybe even better, create a fact that lists all known keyrings and then use the GpgKeys
fact for each of those keyrings to get all the keys. Then you can specifically remove the keyid if it exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. Since there’s no global or common location for keyrings, this will allow specifying the directories to search in — for example, /etc/apt/trusted.gpg.d/ and /usr/share/keyrings/ in the APT context.
|
||
# Clean up empty keyrings | ||
yield ( | ||
f'for keyring in {pattern}; do [ -e "$keyring" ] && ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As referenced in the other comment, if you can list all keys by keyring, then you know if keyrings are going to be empty after removing keyid
from those rings and you can remove them based on that
yield (f'if [ -f "{dest}" ] && ({condition}); then ' f'rm -f "{dest}"; fi') | ||
return | ||
|
||
elif dest and not keyid: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be else
instead of elif
. To me, that seems cleaner because it clearly signals there are only 3 possible combinations of conditions: keyid
is provided and dest
isn't, keyid
and dest
are both provided and lastly, dest
is provided and keyid
isn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it is more an "documentation" elif. To be more explicit.
What about add an else wich raise an exception if we go into an unhandle case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works for me!
elif dest and keyid: | ||
# For APT keyring files, use a simpler approach: | ||
# Check if keys exist in file, and if so, remove the entire file | ||
# This is appropriate for most APT use cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit concerned about "most APT use cases" here. Is there a situation we might be removed a keyfile/keyring that has multiple keys in it?
|
||
|
||
@operation() | ||
def key( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very complex function that covers many different scenarios. I think that from a public API standpoint, that is fine, because we're dealing with 1 resource: keys. But you could break up the function into separate functions that are all called from the key()
function, based on the scenario.
See the docker
operations for an example of how this can be done
Left some more comments @maisim incl. some ideas on how to leverate facts. |
Add new gpg.key and gpg.dearmor operations to manage GPG keys and keyrings. These operations provide a modern alternative to apt-key for managing APT repository keys.
Features:
This is part 1/3 of modernizing APT key management.
3.x
at this time)scripts/dev-test.sh
)scripts/dev-lint.sh
)